package mscs.data;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Method;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;


public class FileDataStore implements IFileDataStore {
	Class readClass;
	File file;
	public FileDataStore(Class readClass, File file) {
		this.readClass = readClass;
		this.file = file;
	}
	public List getObjects() {
		ArrayList<Object> list = new ArrayList<Object>();
                try{
                if(file.exists()) {
                    ObjectInputStream ois = null;
                    try {
                            ois = new ObjectInputStream(new FileInputStream(file));
                            Object tmp = ois.readObject();
                            list = (ArrayList<Object>)tmp;
                            //list = (ArrayList<Object>) ois.readObject();
                    } catch (Exception e){
                            e.printStackTrace();
                    } finally {
                            ois.close();
                            return list;
                    }
                } else {
                    return list;
                }
                } catch(Exception e) {
                    e.printStackTrace();;
                    return list;
                }
	}
	public void update(List list) {
		ObjectOutputStream oos = null;
		try {
			oos = new ObjectOutputStream(new FileOutputStream(file));
                        oos.writeObject(list);
                        oos.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	public void add(List list) {
            try {
            List newList = getObjects();
            newList.addAll(list);
            update(newList);
            } catch(Exception e) {
                e.printStackTrace();
            }
	}

    public List getObjectsByAttr(String key, String value) {
        return searchObjectsByAttr(key, "^"+ value +"$");
    }

    public List searchObjectsByAttr(String key, String regexp) {
        ArrayList<Object> list = new ArrayList<Object>();
        try {
           ArrayList<Object> allList = (ArrayList<Object>)getObjects();
           String methodName = "get" + key.substring(0, 1).toUpperCase() + key.substring(1);
           Method method = readClass.getMethod(methodName);
           Class type = method.getReturnType();
           for(Object obj : allList) {
                String result = typeToString(type, method.invoke(readClass.cast(obj)));
                Pattern pattern = Pattern.compile(regexp);
                Matcher matcher = pattern.matcher(result);
                if(matcher.matches()) {
                    list.add(obj);
                }
            }
        } catch(Exception e) {
            e.printStackTrace();
        } finally {
            return list;
        }
    }
    
    private String typeToString(Class type, Object obj) {
        try {
        if (Date.class.equals(type)) {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            return sdf.format((Date)obj);
        } else {
            return obj.toString();
        }
        } catch(Exception e) {
            e.printStackTrace();
            return "";
        }
    }
    
    public void deleteByIndex(int[] index) {
        try {
            List list = getObjects();
            for (int i = 0; i < index.length; i++) {
                list.remove(index[i]);
            }
            update(list);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
